home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC_Samples / palette / dibapi.cpp next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  8.9 KB  |  331 lines

  1. //  dibapi.cpp
  2. //
  3. //  Source file for Device-Independent Bitmap (DIB) API.  Provides
  4. //  the following functions:
  5. //
  6. //  PaintDIB()          - Painting routine for a DIB
  7. //  CreateDIBPalette()  - Creates a palette from a DIB
  8. //  DIBWidth()          - Gets the width of the DIB
  9. //  DIBHeight()         - Gets the height of the DIB
  10. //  PaletteSize()       - Gets the size required to store the DIB's palette
  11. //  DIBNumColors()      - Calculates the number of colors
  12. //                        in the DIB's color table
  13. //
  14. // This is a part of the Microsoft Foundation Classes C++ library.
  15. // Copyright (C) 1999 Microsoft Corporation
  16. // All rights reserved.
  17. //
  18. // This source code is only intended as a supplement to the
  19. // Microsoft Foundation Classes Reference and related
  20. // electronic documentation provided with the library.
  21. // See these sources for detailed information regarding the
  22. // Microsoft Foundation Classes product.
  23.  
  24. #include "stdafx.h"
  25. #include "dibapi.h"
  26.  
  27. #include "mainfrm.h"
  28.  
  29. /*************************************************************************
  30.  *
  31.  * PaintDIB()
  32.  *
  33.  * Parameters:
  34.  *
  35.  * HDC hDC          - DC to do output to
  36.  *
  37.  * LPRECT lpDCRect  - rectangle on DC to do output to
  38.  *
  39.  * HDIB hDIB        - handle to global memory with a DIB spec
  40.  *                    in it followed by the DIB bits
  41.  *
  42.  * LPRECT lpDIBRect - rectangle of DIB to output into lpDCRect
  43.  *
  44.  * CPalette* pPal   - pointer to CPalette containing DIB's palette
  45.  *
  46.  * Return Value:
  47.  *
  48.  * BOOL             - TRUE if DIB was drawn, FALSE otherwise
  49.  *
  50.  * Description:
  51.  *   Painting routine for a DIB.  Calls StretchDIBits() or
  52.  *   SetDIBitsToDevice() to paint the DIB.  The DIB is
  53.  *   output to the specified DC, at the coordinates given
  54.  *   in lpDCRect.  The area of the DIB to be output is
  55.  *   given by lpDIBRect.
  56.  *
  57.  ************************************************************************/
  58.  
  59. BOOL WINAPI PaintDIB(HDC     hDC,
  60.                     LPRECT  lpDCRect,
  61.                     HDIB    hDIB,
  62.                     LPRECT  lpDIBRect,
  63.                     CPalette* pPal)
  64. {
  65.     LPSTR    lpDIBHdr;            // Pointer to BITMAPINFOHEADER
  66.     LPSTR    lpDIBBits;           // Pointer to DIB bits
  67.     BOOL     bSuccess=FALSE;      // Success/fail flag
  68.     HPALETTE hPal=NULL;           // Our DIB's palette
  69.     HPALETTE hOldPal=NULL;        // Previous palette
  70.  
  71.     /* Check for valid DIB handle */
  72.     if (hDIB == NULL)
  73.         return FALSE;
  74.  
  75.     /* Lock down the DIB, and get a pointer to the beginning of the bit
  76.      *  buffer
  77.      */
  78.     lpDIBHdr  = (LPSTR)hDIB;
  79.     lpDIBBits = (lpDIBHdr + *(LPDWORD)lpDIBHdr + ::PaletteSize(lpDIBHdr));
  80.  
  81.     // Get the DIB's palette, then select it into DC
  82.     if (pPal != NULL)
  83.     {
  84.         hPal = (HPALETTE) pPal->m_hObject;
  85.  
  86.         // Select as background since we have
  87.         // already realized in forground if needed
  88.         hOldPal = ::SelectPalette(hDC, hPal, TRUE);
  89.     }
  90.  
  91.     HDC hDCSrc = CreateCompatibleDC(hDC);
  92.  
  93.     LPSTR lpBits; // Pointer to DIB bits
  94.  
  95.     HBITMAP hBitmap = ::CreateDIBSection(hDC, (BITMAPINFO*)(lpDIBHdr), DIB_RGB_COLORS, (void**)&lpBits, NULL, 0);
  96.     DWORD   dwSize = GlobalSize(hDIB) - sizeof(BITMAPINFOHEADER) - 256 * sizeof(RGBQUAD) - 24;
  97.     memcpy(lpBits, lpDIBBits, dwSize);
  98.  
  99.  
  100.     HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hDCSrc, (HGDIOBJ)hBitmap);
  101.     ::BitBlt( hDC, 0, 0, RECTWIDTH(lpDCRect), RECTHEIGHT(lpDCRect), hDCSrc, 0, 0, SRCCOPY );
  102.     ::SelectObject(hDCSrc, hOldBitmap);
  103.  
  104.     
  105.     ::DeleteObject(hBitmap);
  106.     ::DeleteDC(hDCSrc);
  107.  
  108.     /* Reselect old palette */
  109.     if (hOldPal != NULL)
  110.         ::SelectPalette(hDC, hOldPal, TRUE);
  111.  
  112.    return bSuccess;
  113. }
  114.  
  115. /*************************************************************************
  116.  *
  117.  * CreateDIBPalette()
  118.  *
  119.  * Parameter:
  120.  *
  121.  * HDIB hDIB        - specifies the DIB
  122.  *
  123.  * Return Value:
  124.  *
  125.  * HPALETTE         - specifies the palette
  126.  *
  127.  * Description:
  128.  *
  129.  * This function creates a palette from a DIB by allocating memory for the
  130.  * logical palette, reading and storing the colors from the DIB's color table
  131.  * into the logical palette, creating a palette from this logical palette,
  132.  * and then returning the palette's handle. This allows the DIB to be
  133.  * displayed using the best possible colors (important for DIBs with 256 or
  134.  * more colors).
  135.  *
  136.  ************************************************************************/
  137.  
  138.  
  139. BOOL WINAPI CreateDIBPalette(HDIB hDIB, CPalette* pPal)
  140. {
  141.     LPLOGPALETTE lpPal;      // pointer to a logical palette
  142.     HANDLE hLogPal;          // handle to a logical palette
  143.     HPALETTE hPal = NULL;    // handle to a palette
  144.     int i;                   // loop index
  145.     WORD wNumColors;         // number of colors in color table
  146.     LPSTR lpbi;              // pointer to packed-DIB
  147.     LPBITMAPINFO lpbmi;      // pointer to BITMAPINFO structure
  148.     BOOL bResult = FALSE;
  149.  
  150.     /* if handle to DIB is invalid, return FALSE */
  151.  
  152.     if (hDIB == NULL)
  153.       return FALSE;
  154.  
  155.    lpbi = (LPSTR)hDIB;
  156.  
  157.    /* get pointer to BITMAPINFO */
  158.    lpbmi = (LPBITMAPINFO)lpbi;
  159.  
  160.    /* get the number of colors in the DIB */
  161.    wNumColors = ::DIBNumColors(lpbi);
  162.  
  163.    if (wNumColors != 0)
  164.    {
  165.         /* allocate memory block for logical palette */
  166.         hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)
  167.                                     + sizeof(PALETTEENTRY)
  168.                                     * wNumColors);
  169.  
  170.         /* if not enough memory, clean up and return NULL */
  171.         if (hLogPal == 0)
  172.             return FALSE;
  173.  
  174.         lpPal = (LPLOGPALETTE)hLogPal;
  175.  
  176.         /* set version and number of palette entries */
  177.         lpPal->palVersion = PALVERSION;
  178.         lpPal->palNumEntries = (WORD)wNumColors;
  179.  
  180.         for (i = 0; i < (int)wNumColors; i++)
  181.         {
  182.             lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
  183.             lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
  184.             lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
  185.             lpPal->palPalEntry[i].peFlags = 0;
  186.         }
  187.  
  188.         /* create the palette and get handle to it */
  189.         bResult = pPal->CreatePalette(lpPal);
  190.         ::GlobalFree((HGLOBAL) hLogPal);
  191.     }
  192.  
  193.     return bResult;
  194. }
  195.  
  196.  
  197. /*************************************************************************
  198.  *
  199.  * DIBWidth()
  200.  *
  201.  * Parameter:
  202.  *
  203.  * LPSTR lpbi       - pointer to packed-DIB memory block
  204.  *
  205.  * Return Value:
  206.  *
  207.  * DWORD            - width of the DIB
  208.  *
  209.  * Description:
  210.  *
  211.  * This function gets the width of the DIB from the BITMAPINFOHEADER
  212.  *
  213.  ************************************************************************/
  214.  
  215.  
  216. DWORD WINAPI DIBWidth(LPSTR lpDIB)
  217. {
  218.     LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER)lpDIB;
  219.     return lpbmi->biWidth;
  220. }
  221.  
  222.  
  223. /*************************************************************************
  224.  *
  225.  * DIBHeight()
  226.  *
  227.  * Parameter:
  228.  *
  229.  * LPSTR lpbi       - pointer to packed-DIB memory block
  230.  *
  231.  * Return Value:
  232.  *
  233.  * DWORD            - height of the DIB
  234.  *
  235.  * Description:
  236.  *
  237.  * This function gets the height of the DIB from the BITMAPINFOHEADER
  238.  *
  239.  ************************************************************************/
  240.  
  241.  
  242. DWORD WINAPI DIBHeight(LPSTR lpDIB)
  243. {
  244.     LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER)lpDIB;
  245.     return lpbmi->biHeight;
  246. }
  247.  
  248.  
  249. /*************************************************************************
  250.  *
  251.  * PaletteSize()
  252.  *
  253.  * Parameter:
  254.  *
  255.  * LPSTR lpbi       - pointer to packed-DIB memory block
  256.  *
  257.  * Return Value:
  258.  *
  259.  * WORD             - size of the color palette of the DIB
  260.  *
  261.  * Description:
  262.  *
  263.  * This function gets the size required to store the DIB's palette by
  264.  * multiplying the number of colors by the size of an RGBQUAD 
  265.  *
  266.  ************************************************************************/
  267.  
  268.  
  269. WORD WINAPI PaletteSize(LPSTR lpbi)
  270. {
  271.     return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBQUAD));
  272. }
  273.  
  274.  
  275. /*************************************************************************
  276.  *
  277.  * DIBNumColors()
  278.  *
  279.  * Parameter:
  280.  *
  281.  * LPSTR lpbi       - pointer to packed-DIB memory block
  282.  *
  283.  * Return Value:
  284.  *
  285.  * WORD             - number of colors in the color table
  286.  *
  287.  * Description:
  288.  *
  289.  * This function calculates the number of colors in the DIB's color table
  290.  * by finding the bits per pixel for the DIB. If bits per pixel is 1: 
  291.  * colors=2, if 4: colors=16, if 8: colors=256, if 24, no colors in color 
  292.  * table.
  293.  *
  294.  ************************************************************************/
  295.  
  296.  
  297. WORD WINAPI DIBNumColors(LPSTR lpbi)
  298. {
  299.     WORD wBitCount;  // DIB bit count
  300.  
  301.     /*  If this is a Windows-style DIB, the number of colors in the
  302.      *  color table can be less than the number of bits per pixel
  303.      *  allows for (i.e. lpbi->biClrUsed can be set to some value).
  304.      *  If this is the case, return the appropriate value.
  305.      */
  306.  
  307.     DWORD dwClrUsed;
  308.  
  309.     dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
  310.     if (dwClrUsed != 0)
  311.         return (WORD)dwClrUsed;
  312.  
  313.     /*  Calculate the number of colors in the color table based on
  314.      *  the number of bits per pixel for the DIB.
  315.      */
  316.     wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
  317.     /* return number of colors based on bits per pixel */
  318.     switch (wBitCount)
  319.     {
  320.         case 1:
  321.             return 2;
  322.         case 4:
  323.             return 16;
  324.         case 8:
  325.             return 256;
  326.         default:
  327.             return 0;
  328.     }
  329. }
  330.  
  331.